package huixue.cn.com.rxapp.widget.kline;

import android.content.Context;
import android.graphics.Canvas;
import android.support.annotation.Nullable;
import android.support.annotation.Px;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.Scroller;

import java.util.ArrayList;

import huixue.cn.com.rxapp.util.LogUtils;
import huixue.cn.com.rxapp.widget.data.StickData;
import huixue.cn.com.rxapp.widget.util.DrawUtils;
import huixue.cn.com.rxapp.widget.util.GridUtils;
import huixue.cn.com.rxapp.widget.util.IndexParseUtil;
import huixue.cn.com.rxapp.widget.util.LineUtil;

/**
 * Created by Administrator on 2018/8/14.
 */

public class KLineView2 extends View {
    //烛形图加空白的宽度和烛形图宽度之比
    public static final float WIDTH_SCALE = 1.2f;
    //烛形图和右侧空白的宽度
    public float DEFUALT_WIDTH = 19;
    //K线所有数据
    private ArrayList<StickData> data;
    //K线展示的数据
    private ArrayList<StickData> showList;
    //一屏烛形图数量
    private int drawCount;
    //没两个烛形图x轴的距离
    private float candleXDistance;

    //当前画图偏移量（往右滑动之后）
    private int offset;
    //y轴最大值
    protected double yMax;
    //y轴最小值
    protected double yMin;

    protected float yUnit;
    protected float xUnit;

    //总宽
    protected float mWidth;
    //总高
    protected float mHeight;

    //分时图,K线高度
    protected float mainH;
    //指标高度
    protected float indexH;

    //指标左上y坐标
    protected float indexStartY;
    //时间左上Y坐标
    protected float timeStartY;

    private VelocityTracker mVelocityTracker;

    /**
     * 计算手指滑动的距离
     */
    private float mLastX;

    private Scroller mScroller;

    /**
     * 最小的边界值
     */
    private int mMinScrollX;

    /**
     * 最大的边界值
     */
    private int mMaxScrollX;

    /**
     * fling的最小阈值
     */
    private int mMinVelocity;

    /**
     * fling的最大速度
     */
    private int mMaxVelocity;


    public KLineView2(Context context) {
        super(context);
        //关闭硬件加速，不然虚线显示为实线了
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    public KLineView2(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        //关闭硬件加速，不然虚线显示为实线了
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        mVelocityTracker = VelocityTracker.obtain();


        mScroller = new Scroller(getContext());

        ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext());
        mMinVelocity = viewConfiguration.getScaledMinimumFlingVelocity();
        mMaxVelocity = viewConfiguration.getScaledMaximumFlingVelocity();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        initWidthAndHeight();
        //2，画网格
        if(!flag){
            //drawGrid(canvas);
        }
        LogUtils.e("offset=="+offset);
        //4，如果是K线另外画烛形图
        drawCandles(canvas);

    }

    private  void initWidthAndHeight(){
        mHeight = getMeasuredHeight();
        mWidth = getMeasuredWidth();

        mainH = mHeight * ChartConstant.MAIN_SCALE;

        indexH = mHeight* ChartConstant.INDEX_SCALE;

        indexStartY = mHeight - indexH;

        timeStartY = indexStartY - mHeight * ChartConstant.TIME_SCALE;

        init();

    }

    protected void init() {
        if(data == null) return;
        drawCount = (int) (mWidth / DEFUALT_WIDTH);
        mMaxScrollX = (int)(data.size()*DEFUALT_WIDTH)+100-(int)mWidth;
        candleXDistance = drawCount * WIDTH_SCALE;
        if(data != null && data.size() > 0) {
            if(drawCount < data.size()) {
                getShowList(offset);
            }else{
                showList = new ArrayList<>();
                showList.addAll(data);
            }
        }

        if(showList == null) return;

        float[] low = new float[showList.size()];
        float[] high = new float[showList.size()];

        int i = 0;
        for(StickData d : showList) {
            low[i] = (float) d.getLow();
            high[i] = (float) d.getHigh();
            i++;
        }

        float[] maxAndMin = LineUtil.getMaxAndMin(low, high);
        yMax = maxAndMin[0];
        yMin = maxAndMin[1];

        yUnit = (float) (yMax - yMin) / mainH;
        xUnit = mWidth / drawCount;
    }


    public void setDataAndInvalidate(ArrayList<StickData> data) {
        this.data = data;
        parseData();
        postInvalidate();
    }

    /**
     * 获取页面一页可展示的数据
     */
    private void getShowList(int offset) {
        if(offset != 0 && data.size() - drawCount - offset < 0) {
            offset = data.size() - drawCount;
        }
        showList = new ArrayList<>();
        showList.addAll(data.subList(data.size() - drawCount - offset, data.size() - offset));
    }


    protected void drawGrid(Canvas canvas) {
        GridUtils.drawGrid(canvas, mWidth, mainH);
        GridUtils.drawIndexGrid(canvas, indexStartY, mWidth, indexH);
    }

    protected void drawCandles(Canvas canvas) {
        if(data == null || data.size() == 0) return;
        float x = 0;
        if(showList == null || showList.size() == 0) return;
        //计算出页面能显示多少个
        for(int i = 0; i <data.size(); i++) {
            if(drawCount < data.size()) {
                x = mWidth - (mWidth / drawCount * (showList.size() - i));
            } else {
                x = (mWidth / drawCount *i);
            }
            DrawUtils.drawCandle(canvas,
                    parseNumber(data.get(i).getHigh()),
                    parseNumber(data.get(i).getLow()),
                    parseNumber(data.get(i).getOpen()),
                    parseNumber(data.get(i).getClose()),
                    x,
                    parseNumber(data.get(i).getHigh()),
                    candleXDistance,
                    mWidth);
        }
    }

    /**
     * 把传入的参数计算成坐标，直接展示到界面上
     * @param input
     * @return 返回里面的StickData的最高价最低价，都是可以直接显示在坐标上的
     */
    private float parseNumber(double input) {
        return mainH - (float)(( input - yMin) / yUnit);
    }

    /**
     * 计算各指标
     */
    private void parseData() {
        offset = 0;
        //根据当前显示的指标类型，优先计算指标
        IndexParseUtil.initSma(this.data);

        /*//把暂时不显示的计算，放在线程中去完成，避免阻塞主线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                switch (indexType) {
                    case ChartConstant.INDEX_VOL:
                        IndexParseUtil.initMACD(data);
                        IndexParseUtil.initKDJ(data);
                        break;
                    case  ChartConstant.INDEX_MACD:
                        IndexParseUtil.initKDJ(data);
                        break;
                    case  ChartConstant.INDEX_KDJ:
                        IndexParseUtil.initMACD(data);
                        break;
                }
            }
        }).start();*/
    }

    boolean flag = false;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();//获得VelocityTracker类实例
        }
        mVelocityTracker.addMovement(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                getParent().requestDisallowInterceptTouchEvent(true);
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }
                mVelocityTracker.clear();

                mLastX = event.getX();

                return true;
            case MotionEvent.ACTION_MOVE:


                float x = event.getX();
                float delX = x - mLastX;
                if(data != null && drawCount < data.size() && Math.abs(delX) > DEFUALT_WIDTH) {
                    int temp = offset + (int)(0 - delX / DEFUALT_WIDTH);
                    if(temp < 0 || temp + drawCount > data.size()) {

                    } else {
                        offset = temp;
                    }
                    scrollBy(-(int) delX, 0);

                    mLastX = x;
                    flag = true;
                }

                return true;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:

                final VelocityTracker velocityTracker = mVelocityTracker;
                // 1000 provides pixels per second
                // 设置maxVelocity值为0.01时，速率大于0.01时，显示的速率都是0.01,速率小于0.01时，显示正常
                velocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
                float xVelocity = velocityTracker.getXVelocity();
                if (Math.abs(xVelocity) >= mMinVelocity) {
                    fling(-(int) xVelocity);
                } else {
                    //scrollExactly();
                }

                velocityTracker.clear();
                flag = false;
                return true;
        }

        return super.onTouchEvent(event);
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {

            int x = mScroller.getCurrX();

            scrollTo(x, 0);

            invalidate();

            // 惯性滑动即将结束，此时需要将刻度校准到刻度线上
            if (!mScroller.computeScrollOffset()) {
                //scrollExactly();
            }
        }
    }

    public void fling(int velocityX) {
        mScroller.fling(getScrollX(), getScrollY(), velocityX, 0, mMinScrollX, mMaxScrollX, 0,0);
    }

    @Override
    public void scrollTo(@Px int x, @Px int y) {

        if (x < mMinScrollX) {
            x = mMinScrollX;
        } else if (x > mMaxScrollX) {
            x = mMaxScrollX;
        }

        if (x != getScrollX()) {
            super.scrollTo(x, y);
        }


    }
}
